home *** CD-ROM | disk | FTP | other *** search
/ DOS Vuser Deluxe 2003 October / DOS Vuser Deluxe 2003 Oct - Disc 1.iso / FREE / INTERNET / iria107a.lzh / script / sre_parse.pyc (.txt) < prev    next >
Python Compiled Bytecode  |  2000-11-17  |  21KB  |  728 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.0)
  3.  
  4. import string
  5. import sys
  6. from sre_constants import *
  7. SPECIAL_CHARS = '.\\[{()*+?^$|'
  8. REPEAT_CHARS = '*+?{'
  9. DIGITS = tuple('0123456789')
  10. OCTDIGITS = tuple('01234567')
  11. HEXDIGITS = tuple('0123456789abcdefABCDEF')
  12. WHITESPACE = tuple(' \t\n\r\x0b\x0c')
  13. ESCAPES = {
  14.     '\\a': (LITERAL, 7),
  15.     '\\b': (LITERAL, 8),
  16.     '\\f': (LITERAL, 12),
  17.     '\\n': (LITERAL, 10),
  18.     '\\r': (LITERAL, 13),
  19.     '\\t': (LITERAL, 9),
  20.     '\\v': (LITERAL, 11),
  21.     '\\\\': (LITERAL, ord('\\')) }
  22. CATEGORIES = {
  23.     '\\A': (AT, AT_BEGINNING),
  24.     '\\b': (AT, AT_BOUNDARY),
  25.     '\\B': (AT, AT_NON_BOUNDARY),
  26.     '\\d': (IN, [
  27.         (CATEGORY, CATEGORY_DIGIT)]),
  28.     '\\D': (IN, [
  29.         (CATEGORY, CATEGORY_NOT_DIGIT)]),
  30.     '\\s': (IN, [
  31.         (CATEGORY, CATEGORY_SPACE)]),
  32.     '\\S': (IN, [
  33.         (CATEGORY, CATEGORY_NOT_SPACE)]),
  34.     '\\w': (IN, [
  35.         (CATEGORY, CATEGORY_WORD)]),
  36.     '\\W': (IN, [
  37.         (CATEGORY, CATEGORY_NOT_WORD)]),
  38.     '\\Z': (AT, AT_END) }
  39. FLAGS = {
  40.     'i': SRE_FLAG_IGNORECASE,
  41.     'L': SRE_FLAG_LOCALE,
  42.     'm': SRE_FLAG_MULTILINE,
  43.     's': SRE_FLAG_DOTALL,
  44.     'x': SRE_FLAG_VERBOSE,
  45.     't': SRE_FLAG_TEMPLATE,
  46.     'u': SRE_FLAG_UNICODE }
  47.  
  48. class Pattern:
  49.     
  50.     def __init__(self):
  51.         self.flags = 0
  52.         self.groups = 1
  53.         self.groupdict = { }
  54.  
  55.     
  56.     def getgroup(self, name = None):
  57.         gid = self.groups
  58.         self.groups = gid + 1
  59.         if name:
  60.             self.groupdict[name] = gid
  61.         
  62.         return gid
  63.  
  64.  
  65.  
  66. class SubPattern:
  67.     
  68.     def __init__(self, pattern, data = None):
  69.         self.pattern = pattern
  70.         if not data:
  71.             data = []
  72.         
  73.         self.data = data
  74.         self.width = None
  75.  
  76.     
  77.     def dump(self, level = 0):
  78.         nl = 1
  79.         for op, av in self.data:
  80.             print level * '  ' + op,
  81.             nl = 0
  82.             if op == 'in':
  83.                 print 
  84.                 nl = 1
  85.                 for op, a in av:
  86.                     print (level + 1) * '  ' + op, a
  87.                 
  88.             elif op == 'branch':
  89.                 print 
  90.                 nl = 1
  91.                 i = 0
  92.                 for a in av[1]:
  93.                     if i > 0:
  94.                         print level * '  ' + 'or'
  95.                     
  96.                     a.dump(level + 1)
  97.                     nl = 1
  98.                     i = i + 1
  99.                 
  100.             elif type(av) in (type(()), type([])):
  101.                 for a in av:
  102.                     pass
  103.                 
  104.             else:
  105.                 print av,
  106.                 nl = 0
  107.             if not nl:
  108.                 print 
  109.             
  110.         
  111.  
  112.     
  113.     def __repr__(self):
  114.         return repr(self.data)
  115.  
  116.     
  117.     def __len__(self):
  118.         return len(self.data)
  119.  
  120.     
  121.     def __delitem__(self, index):
  122.         del self.data[index]
  123.  
  124.     
  125.     def __getitem__(self, index):
  126.         return self.data[index]
  127.  
  128.     
  129.     def __setitem__(self, index, code):
  130.         self.data[index] = code
  131.  
  132.     
  133.     def __getslice__(self, start, stop):
  134.         return SubPattern(self.pattern, self.data[start:stop])
  135.  
  136.     
  137.     def insert(self, index, code):
  138.         self.data.insert(index, code)
  139.  
  140.     
  141.     def append(self, code):
  142.         self.data.append(code)
  143.  
  144.     
  145.     def getwidth(self):
  146.         if self.width:
  147.             return self.width
  148.         
  149.         lo = hi = 0x0L
  150.         for op, av in self.data:
  151.             if op is BRANCH:
  152.                 i = sys.maxint
  153.                 j = 0
  154.                 for av in av[1]:
  155.                     (l, h) = av.getwidth()
  156.                     i = min(i, l)
  157.                     j = max(j, h)
  158.                 
  159.                 lo = lo + i
  160.                 hi = hi + j
  161.             elif op is CALL:
  162.                 (i, j) = av.getwidth()
  163.                 lo = lo + i
  164.                 hi = hi + j
  165.             elif op is SUBPATTERN:
  166.                 (i, j) = av[1].getwidth()
  167.                 lo = lo + i
  168.                 hi = hi + j
  169.             elif op in (MIN_REPEAT, MAX_REPEAT):
  170.                 (i, j) = av[2].getwidth()
  171.                 lo = lo + long(i) * av[0]
  172.                 hi = hi + long(j) * av[1]
  173.             elif op in (ANY, RANGE, IN, LITERAL, NOT_LITERAL, CATEGORY):
  174.                 lo = lo + 1
  175.                 hi = hi + 1
  176.             elif op == SUCCESS:
  177.                 break
  178.             
  179.         
  180.         self.width = (int(min(lo, sys.maxint)), int(min(hi, sys.maxint)))
  181.         return self.width
  182.  
  183.  
  184.  
  185. class Tokenizer:
  186.     
  187.     def __init__(self, string):
  188.         self.string = string
  189.         self.index = 0
  190.         self._Tokenizer__next()
  191.  
  192.     
  193.     def __next(self):
  194.         if self.index >= len(self.string):
  195.             self.next = None
  196.             return None
  197.         
  198.         char = self.string[self.index]
  199.         if char[0] == '\\':
  200.             
  201.             try:
  202.                 c = self.string[self.index + 1]
  203.             except IndexError:
  204.                 raise error, 'bogus escape'
  205.  
  206.             char = char + c
  207.         
  208.         self.index = self.index + len(char)
  209.         self.next = char
  210.  
  211.     
  212.     def match(self, char, skip = 1):
  213.         if char == self.next:
  214.             if skip:
  215.                 self._Tokenizer__next()
  216.             
  217.             return 1
  218.         
  219.         return 0
  220.  
  221.     
  222.     def get(self):
  223.         this = self.next
  224.         self._Tokenizer__next()
  225.         return this
  226.  
  227.     
  228.     def tell(self):
  229.         return (self.index, self.next)
  230.  
  231.     
  232.     def seek(self, index):
  233.         (self.index, self.next) = index
  234.  
  235.  
  236.  
  237. def isident(char):
  238.     return None if char <= char else None if char <= char else char == '_'
  239.  
  240.  
  241. def isdigit(char):
  242.     return None if char <= char else char <= '9'
  243.  
  244.  
  245. def isname(name):
  246.     if not isident(name[0]):
  247.         return 0
  248.     
  249.     for char in name:
  250.         pass
  251.     
  252.     return 1
  253.  
  254.  
  255. def _group(escape, groups):
  256.     
  257.     try:
  258.         gid = int(escape[1:])
  259.         if gid and gid < groups:
  260.             return gid
  261.     except ValueError:
  262.         pass
  263.  
  264.     return None
  265.  
  266.  
  267. def _class_escape(source, escape):
  268.     code = ESCAPES.get(escape)
  269.     if code:
  270.         return code
  271.     
  272.     code = CATEGORIES.get(escape)
  273.     if code:
  274.         return code
  275.     
  276.     
  277.     try:
  278.         if escape[1:2] == 'x':
  279.             while source.next in HEXDIGITS and len(escape) < 4:
  280.                 escape = escape + source.get()
  281.             escape = escape[2:]
  282.             if len(escape) != 2:
  283.                 raise error, 'bogus escape: %s' % repr('\\' + escape)
  284.             
  285.             return (LITERAL, int(escape, 16) & 255)
  286.         elif str(escape[1:2]) in OCTDIGITS:
  287.             while source.next in OCTDIGITS and len(escape) < 5:
  288.                 escape = escape + source.get()
  289.             escape = escape[1:]
  290.             return (LITERAL, int(escape, 8) & 255)
  291.         
  292.         if len(escape) == 2:
  293.             return (LITERAL, ord(escape[1]))
  294.     except ValueError:
  295.         pass
  296.  
  297.     raise error, 'bogus escape: %s' % repr(escape)
  298.  
  299.  
  300. def _escape(source, escape, state):
  301.     code = CATEGORIES.get(escape)
  302.     if code:
  303.         return code
  304.     
  305.     code = ESCAPES.get(escape)
  306.     if code:
  307.         return code
  308.     
  309.     
  310.     try:
  311.         if escape[1:2] == 'x':
  312.             while source.next in HEXDIGITS and len(escape) < 4:
  313.                 escape = escape + source.get()
  314.             if len(escape) != 4:
  315.                 raise ValueError
  316.             
  317.             return (LITERAL, int(escape[2:], 16) & 255)
  318.         elif escape[1:2] == '0':
  319.             while source.next in OCTDIGITS and len(escape) < 4:
  320.                 escape = escape + source.get()
  321.             return (LITERAL, int(escape[1:], 8) & 255)
  322.         elif escape[1:2] in DIGITS:
  323.             here = source.tell()
  324.             if source.next in DIGITS:
  325.                 escape = escape + source.get()
  326.                 if escape[1] in OCTDIGITS and escape[2] in OCTDIGITS and source.next in OCTDIGITS:
  327.                     escape = escape + source.get()
  328.                     return (LITERAL, int(escape[1:], 8) & 255)
  329.                 
  330.             
  331.             group = _group(escape, state.groups)
  332.             if group:
  333.                 return (GROUPREF, group)
  334.             
  335.             raise ValueError
  336.         
  337.         if len(escape) == 2:
  338.             return (LITERAL, ord(escape[1]))
  339.     except ValueError:
  340.         pass
  341.  
  342.     raise error, 'bogus escape: %s' % repr(escape)
  343.  
  344.  
  345. def _parse_sub(source, state, nested = 1):
  346.     items = []
  347.     while 1:
  348.         items.append(_parse(source, state))
  349.         if source.match('|'):
  350.             continue
  351.         
  352.         if not nested:
  353.             break
  354.         
  355.         if not (source.next) or source.match(')', 0):
  356.             break
  357.         else:
  358.             raise error, 'pattern not properly closed'
  359.     if len(items) == 1:
  360.         return items[0]
  361.     
  362.     subpattern = SubPattern(state)
  363.     while 1:
  364.         prefix = None
  365.         for item in items:
  366.             if prefix is None:
  367.                 prefix = item[0]
  368.             elif item[0] != prefix:
  369.                 break
  370.             
  371.         else:
  372.             for item in items:
  373.                 del item[0]
  374.             
  375.         break
  376.     for item in items:
  377.         pass
  378.     else:
  379.         set = []
  380.         for item in items:
  381.             set.append(item[0])
  382.         
  383.         return subpattern
  384.     subpattern.append((BRANCH, (None, items)))
  385.     return subpattern
  386.  
  387.  
  388. def _parse(source, state):
  389.     subpattern = SubPattern(state)
  390.     while 1:
  391.         if source.next in ('|', ')'):
  392.             break
  393.         
  394.         this = source.get()
  395.         if this is None:
  396.             break
  397.         
  398.         if state.flags & SRE_FLAG_VERBOSE:
  399.             if this in WHITESPACE:
  400.                 continue
  401.             
  402.             if this == '#':
  403.                 while 1:
  404.                     this = source.get()
  405.                     if this in (None, '\n'):
  406.                         break
  407.                     
  408.                 continue
  409.             
  410.         
  411.         if this and this[0] not in SPECIAL_CHARS:
  412.             subpattern.append((LITERAL, ord(this)))
  413.         elif this == '[':
  414.             set = []
  415.             if source.match('^'):
  416.                 set.append((NEGATE, None))
  417.             
  418.             start = set[:]
  419.             while 1:
  420.                 this = source.get()
  421.                 if this == ']' and set != start:
  422.                     break
  423.                 elif this and this[0] == '\\':
  424.                     code1 = _class_escape(source, this)
  425.                 elif this:
  426.                     code1 = (LITERAL, ord(this))
  427.                 else:
  428.                     raise error, 'unexpected end of regular expression'
  429.                 if source.match('-'):
  430.                     this = source.get()
  431.                     if this == ']':
  432.                         if code1[0] is IN:
  433.                             code1 = code1[1][0]
  434.                         
  435.                         set.append(code1)
  436.                         set.append((LITERAL, ord('-')))
  437.                         break
  438.                     elif this[0] == '\\':
  439.                         code2 = _class_escape(source, this)
  440.                     else:
  441.                         code2 = (LITERAL, ord(this))
  442.                     if code1[0] != LITERAL or code2[0] != LITERAL:
  443.                         raise error, 'illegal range'
  444.                     
  445.                     lo = code1[1]
  446.                     hi = code2[1]
  447.                     if hi < lo:
  448.                         raise error, 'illegal range'
  449.                     
  450.                     set.append((RANGE, (lo, hi)))
  451.                 elif code1[0] is IN:
  452.                     code1 = code1[1][0]
  453.                 
  454.                 set.append(code1)
  455.             if len(set) == 1 and set[0][0] is LITERAL:
  456.                 subpattern.append(set[0])
  457.             elif len(set) == 2 and set[0][0] is NEGATE and set[1][0] is LITERAL:
  458.                 subpattern.append((NOT_LITERAL, set[1][1]))
  459.             else:
  460.                 subpattern.append((IN, set))
  461.         elif this and this[0] in REPEAT_CHARS:
  462.             if this == '?':
  463.                 (min, max) = (0, 1)
  464.             elif this == '*':
  465.                 (min, max) = (0, MAXREPEAT)
  466.             elif this == '+':
  467.                 (min, max) = (1, MAXREPEAT)
  468.             elif this == '{':
  469.                 here = source.tell()
  470.                 (min, max) = (0, MAXREPEAT)
  471.                 lo = hi = ''
  472.                 while source.next in DIGITS:
  473.                     lo = lo + source.get()
  474.                 if source.match(','):
  475.                     while source.next in DIGITS:
  476.                         hi = hi + source.get()
  477.                 else:
  478.                     hi = lo
  479.                 if not source.match('}'):
  480.                     subpattern.append((LITERAL, ord(this)))
  481.                     source.seek(here)
  482.                     continue
  483.                 
  484.                 if lo:
  485.                     min = int(lo)
  486.                 
  487.                 if hi:
  488.                     max = int(hi)
  489.                 
  490.             else:
  491.                 raise error, 'not supported'
  492.             if subpattern:
  493.                 item = subpattern[-1:]
  494.             else:
  495.                 raise error, 'nothing to repeat'
  496.             if source.match('?'):
  497.                 subpattern[-1] = (MIN_REPEAT, (min, max, item))
  498.             else:
  499.                 subpattern[-1] = (MAX_REPEAT, (min, max, item))
  500.         elif this == '.':
  501.             subpattern.append((ANY, None))
  502.         elif this == '(':
  503.             group = 1
  504.             name = None
  505.             if source.match('?'):
  506.                 group = 0
  507.                 if source.match('P'):
  508.                     if source.match('<'):
  509.                         name = ''
  510.                         while 1:
  511.                             char = source.get()
  512.                             if char is None:
  513.                                 raise error, 'unterminated name'
  514.                             
  515.                             if char == '>':
  516.                                 break
  517.                             
  518.                             name = name + char
  519.                         group = 1
  520.                         if not isname(name):
  521.                             raise error, 'illegal character in group name'
  522.                         
  523.                     elif source.match('='):
  524.                         name = ''
  525.                         while 1:
  526.                             char = source.get()
  527.                             if char is None:
  528.                                 raise error, 'unterminated name'
  529.                             
  530.                             if char == ')':
  531.                                 break
  532.                             
  533.                             name = name + char
  534.                         if not isname(name):
  535.                             raise error, 'illegal character in group name'
  536.                         
  537.                         gid = state.groupdict.get(name)
  538.                         if gid is None:
  539.                             raise error, 'unknown group name'
  540.                         
  541.                         subpattern.append((GROUPREF, gid))
  542.                         continue
  543.                     else:
  544.                         char = source.get()
  545.                         if char is None:
  546.                             raise error, 'unexpected end of pattern'
  547.                         
  548.                         raise error, 'unknown specifier: ?P%s' % char
  549.                 elif source.match(':'):
  550.                     group = 2
  551.                 elif source.match('#'):
  552.                     while 1:
  553.                         if source.next is None or source.next == ')':
  554.                             break
  555.                         
  556.                         source.get()
  557.                     if not source.match(')'):
  558.                         raise error, 'unbalanced parenthesis'
  559.                     
  560.                     continue
  561.                 elif source.next in ('=', '!', '<'):
  562.                     char = source.get()
  563.                     dir = 1
  564.                     if char == '<':
  565.                         if source.next not in ('=', '!'):
  566.                             raise error, 'syntax error'
  567.                         
  568.                         dir = -1
  569.                         char = source.get()
  570.                     
  571.                     p = _parse_sub(source, state)
  572.                     if not source.match(')'):
  573.                         raise error, 'unbalanced parenthesis'
  574.                     
  575.                     if char == '=':
  576.                         subpattern.append((ASSERT, (dir, p)))
  577.                     else:
  578.                         subpattern.append((ASSERT_NOT, (dir, p)))
  579.                     continue
  580.                 else:
  581.                     while FLAGS.has_key(source.next):
  582.                         state.flags = state.flags | FLAGS[source.get()]
  583.             
  584.             if group:
  585.                 if group == 2:
  586.                     group = None
  587.                 else:
  588.                     group = state.getgroup(name)
  589.                 p = _parse_sub(source, state)
  590.                 if not source.match(')'):
  591.                     raise error, 'unbalanced parenthesis'
  592.                 
  593.                 subpattern.append((SUBPATTERN, (group, p)))
  594.             else:
  595.                 while 1:
  596.                     char = source.get()
  597.                     if char is None or char == ')':
  598.                         break
  599.                     
  600.                     raise error, 'unknown extension'
  601.         elif this == '^':
  602.             subpattern.append((AT, AT_BEGINNING))
  603.         elif this == '$':
  604.             subpattern.append((AT, AT_END))
  605.         elif this and this[0] == '\\':
  606.             code = _escape(source, this, state)
  607.             subpattern.append(code)
  608.         else:
  609.             raise error, 'parser error'
  610.     return subpattern
  611.  
  612.  
  613. def parse(str, flags = 0, pattern = None):
  614.     source = Tokenizer(str)
  615.     if pattern is None:
  616.         pattern = Pattern()
  617.     
  618.     pattern.flags = flags
  619.     p = _parse_sub(source, pattern, 0)
  620.     tail = source.get()
  621.     if tail == ')':
  622.         raise error, 'unbalanced parenthesis'
  623.     elif tail:
  624.         raise error, 'bogus characters at end of regular expression'
  625.     
  626.     if not (flags & SRE_FLAG_VERBOSE) and p.pattern.flags & SRE_FLAG_VERBOSE:
  627.         return parse(str, p.pattern.flags)
  628.     
  629.     return p
  630.  
  631.  
  632. def parse_template(source, pattern):
  633.     s = Tokenizer(source)
  634.     p = []
  635.     a = p.append
  636.     while 1:
  637.         this = s.get()
  638.         if this is None:
  639.             break
  640.         
  641.         if this and this[0] == '\\':
  642.             if this == '\\g':
  643.                 name = ''
  644.                 if s.match('<'):
  645.                     while 1:
  646.                         char = s.get()
  647.                         if char is None:
  648.                             raise error, 'unterminated group name'
  649.                         
  650.                         if char == '>':
  651.                             break
  652.                         
  653.                         name = name + char
  654.                 
  655.                 if not name:
  656.                     raise error, 'bad group name'
  657.                 
  658.                 
  659.                 try:
  660.                     index = int(name)
  661.                 except ValueError:
  662.                     if not isname(name):
  663.                         raise error, 'illegal character in group name'
  664.                     
  665.                     
  666.                     try:
  667.                         index = pattern.groupindex[name]
  668.                     except KeyError:
  669.                         raise IndexError, 'unknown group name'
  670.  
  671.  
  672.                 a((MARK, index))
  673.             elif len(this) > 1 and this[1] in DIGITS:
  674.                 code = None
  675.                 while 1:
  676.                     group = _group(this, pattern.groups + 1)
  677.                     if group:
  678.                         if s.next not in DIGITS or not _group(this + s.next, pattern.groups + 1):
  679.                             code = (MARK, int(group))
  680.                             break
  681.                         
  682.                     elif s.next in OCTDIGITS:
  683.                         this = this + s.get()
  684.                     else:
  685.                         break
  686.                 if not code:
  687.                     this = this[1:]
  688.                     code = (LITERAL, int(this[-6:], 8) & 255)
  689.                 
  690.                 a(code)
  691.             else:
  692.                 
  693.                 try:
  694.                     a(ESCAPES[this])
  695.                 except KeyError:
  696.                     for c in this:
  697.                         a((LITERAL, ord(c)))
  698.                     
  699.                 except:
  700.                     0
  701.  
  702.         else:
  703.             a((LITERAL, ord(this)))
  704.     return p
  705.  
  706.  
  707. def expand_template(template, match):
  708.     p = []
  709.     a = p.append
  710.     sep = match.string[:0]
  711.     if type(sep) is type(''):
  712.         char = chr
  713.     else:
  714.         char = unichr
  715.     for c, s in template:
  716.         if c is LITERAL:
  717.             a(char(s))
  718.         elif c is MARK:
  719.             s = match.group(s)
  720.             if s is None:
  721.                 raise error, 'empty group'
  722.             
  723.             a(s)
  724.         
  725.     
  726.     return string.join(p, sep)
  727.  
  728.